// UserInteractionManager.cpp
//
#include "UserInteractionManager.h"
#include <QMap>
#include <QAction>
//#include <QTextStream>
#include <QMouseEvent>
#include <QWheelEvent>

#include "MemCheck.h"

using namespace IDS::IDEAS::OpenGLView::Fwk;

// ------------------------------------------------------------------------------------------------
UserInteractionManager::UserInteractionManager(){ clear(); }

// ------------------------------------------------------------------------------------------------
UserInteractionManager::~UserInteractionManager(){ clear(); }

// ------------------------------------------------------------------------------------------------
void UserInteractionManager::clear()
{
	//for( KeyBinds::iterator it = keyBindings.begin(); it != keyBindings.end();	++it)
	//	if( *it )
	//		delete *it;

	keyBindings.clear();
	mouseBindings.clear();
}

// ------------------------------------------------------------------------------------------------
void UserInteractionManager::addKeyBinding(const QString &name, const QString &text, const QString &shortcut, QObject *receiver, const char *method )
{
	QAction *a = new QAction(receiver);
	a->setText(text);
	a->setShortcutContext(Qt::ApplicationShortcut);
	//a->setShortcutContext(Qt::WidgetShortcut);
	a->setShortcut( QKeySequence(shortcut) );

	connect(a, SIGNAL(triggered()), receiver, method);

	keyBindings.insert(name,a);
}

// ------------------------------------------------------------------------------------------------
QAction* UserInteractionManager::getAction(const QString &name)
{
	if( !keyBindings.contains( name ) )
		return NULL;

	return keyBindings[name];
}

// ------------------------------------------------------------------------------------------------
QList<QAction*> UserInteractionManager::getKeyBindings()
{
	return keyBindings.values();
}

// ------------------------------------------------------------------------------------------------
void UserInteractionManager::addMouseBinding(const QString &name, const QString &shortcut)
{
	//QAction *a = new QAction(receiver);
	//a->setText(name);

	//connect(a, SIGNAL(triggered()), receiver, method);

	
	const int plus = shortcut.lastIndexOf("+") + 1;
	
	QString mouseButton = shortcut.mid(plus);

	QString accel = "";
	if( plus > 1 )	 accel = shortcut.left(plus);

	QKeySequence ks(accel);
	QString k = (ks.toString() + mouseButton).toLower();

	mouseBindings.insert(k, name);
}

// ------------------------------------------------------------------------------------------------
QString UserInteractionManager::getMouseAction( QGraphicsSceneWheelEvent *e)
{
	QKeySequence ks( e->modifiers() );

	QString k = (ks.toString() + "Wheel").toLower();

	QString actionName = "";

	MouseBinds::iterator it =  mouseBindings.find( k );
	if( it != mouseBindings.end() )
		actionName = *it;

	return actionName;
}

// ------------------------------------------------------------------------------------------------
QString UserInteractionManager::getMouseAction( QWheelEvent *e)
{
	QKeySequence ks( e->modifiers() );

	QString k = (ks.toString() + "Wheel").toLower();

	QString actionName = "";

	MouseBinds::iterator it =  mouseBindings.find( k );
	if( it != mouseBindings.end() )
		actionName = *it;

	return actionName;
}

// ------------------------------------------------------------------------------------------------
QString UserInteractionManager::getMouseAction( QGraphicsSceneMouseEvent *e)
{
	QKeySequence ks( e->modifiers() );

	QString k = "";
	
	switch( e->button() )
	{
	case Qt::MidButton:		k = (ks.toString() + "MidButton").toLower();	break;
	case Qt::LeftButton:	k = (ks.toString() + "LeftButton").toLower();	break;
	case Qt::RightButton:	k = (ks.toString() + "RightButton").toLower();	break;
	}

	
	QString actionName = "";

	MouseBinds::iterator it =  mouseBindings.find(k);
	if( it != mouseBindings.end() )
		actionName = *it;

	return actionName;
}

// ------------------------------------------------------------------------------------------------
QString UserInteractionManager::getMouseAction( QMouseEvent *e)
{
	QKeySequence ks( e->modifiers() );

	QString k = "";
	
	switch( e->button() )
	{
	case Qt::MidButton:		k = (ks.toString() + "MidButton").toLower();	break;
	case Qt::LeftButton:	k = (ks.toString() + "LeftButton").toLower();	break;
	case Qt::RightButton:	k = (ks.toString() + "RightButton").toLower();	break;
	}

	
	QString actionName = "";

	MouseBinds::iterator it =  mouseBindings.find(k);
	if( it != mouseBindings.end() )
		actionName = *it;

	return actionName;
}


// ------------------------------------------------------------------------------------------------
//int UserInteractionManager::getActionOnKeyEvent(wxKeyEvent &keyEvent)
//{
//	int actionID = -1;
//
//	int currKey = keyEvent.GetKeyCode();
//
//	int currMod =	(keyEvent.ShiftDown()	? wxMOD_SHIFT   : 0) | 
//					(keyEvent.ControlDown() ? wxMOD_CONTROL : 0) |
//					(keyEvent.AltDown()		? wxMOD_ALT     : 0);
//
//	if(currMod == wxMOD_CONTROL && currKey <= 26 )		currKey += 'a'-1;
//	if(currMod == wxMOD_ALTGR                    )		currMod = 0;
//
//	for(UI::iterator it = userInteractions.begin(); it != userInteractions.end() && actionID < 0; ++it)
//	{
//		for(size_t j = 0; j<it->second.keyMouseArr.size(); ++j)
//		{
//			// check the modifiers
//			const bool modCheck = it->second.keyMouseArr[j].modifiers == currMod;
//				
//			// check the key
//			const bool keyCheck = it->second.keyMouseArr[j].key == currKey;
//
//			// if this key combination fits exit with true
//			if(modCheck && keyCheck)
//			{
//				actionID = it->first;
//				break;
//			}
//		}
//	}
//	return actionID;
//}
//
//
//// ------------------------------------------------------------------------------------------------
//int UserInteractionManager::getActionOnMouseEvent(wxMouseEvent &mouseEvent)
//{
//	int actionID = -1;
//
//	int currMod=
//		(mouseEvent.ShiftDown() ? wxMOD_SHIFT : 0) | 
//		(mouseEvent.CmdDown() ? wxMOD_CMD : 0) | 
//		(mouseEvent.AltDown() ? wxMOD_ALT : 0);
//
//	int butDown=
//		(mouseEvent.LeftDown() ? 1 : 0) |
//		(mouseEvent.MiddleDown() ? 2 : 0) |
//		(mouseEvent.RightDown() ? 4 : 0);
//
//	int butUp=
//		(mouseEvent.LeftUp() ? 1 : 0) |
//		(mouseEvent.MiddleUp() ? 2 : 0) |
//		(mouseEvent.RightUp() ? 4 : 0);
//
//	int currBut=
//		(mouseEvent.LeftIsDown() ? 1 : 0) |
//		(mouseEvent.MiddleIsDown() ? 2 : 0) |
//		(mouseEvent.RightIsDown() ? 4 : 0);
//
//
//	for(UI::iterator it = userInteractions.begin(); it != userInteractions.end() && actionID < 0; ++it)
//	{
//		for(size_t j = 0; j<it->second.keyMouseArr.size(); ++j)
//		{			
//			const int mod = it->second.keyMouseArr[j].modifiers;		// check the modifiers
//			const int but = it->second.keyMouseArr[j].mouseButtons; 	// check the mouse button
//
//			bool modCheck   = mod == currMod;
//			bool wheelCheck = it->second.keyMouseArr[j].wheel == (mouseEvent.GetWheelRotation() != 0);
//			bool butCheck   = false;
//			
//			switch( it->second.type ) 
//			{
//			case UserInteraction::Start:	
//				butCheck = but == butDown;	break;
//			case UserInteraction::Update:	
//				butCheck = (but == currBut) && (wheelCheck == false ?  mouseEvent.Dragging() : true);	break;
//			case UserInteraction::End:		
//				butCheck = but == butUp;	break;
//			}
//
//			// if this key/mouse combination fits exit with true
//			if(modCheck && butCheck && wheelCheck)
//			{
//				actionID = it->first;
//				break;
//			}
//		}
//	}
//
//
//#ifdef _DEBUG
//		//Info(wxT("modCheck= %d, butCheck=%d, dragCheck=%d, wheelCheck=%d", modCheck, butCheck, dragCheck, wheelCheck);
//#endif
//	return actionID;
//}

